home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-05-11 | 40.4 KB | 1,204 lines |
- Newsgroups: comp.sources.misc
- From: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Subject: v19i041: dmake - dmake version 3.7, Part20/37
- Message-ID: <1991May12.002115.9491@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 0e4bb607e1af7da290a9b4037c700dde
- Date: Sun, 12 May 1991 00:21:15 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Posting-number: Volume 19, Issue 41
- Archive-name: dmake/part20
- Supersedes: dmake-3.6: Volume 15, Issue 52-77
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # this is dmake.shar.20 (part 20 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file dmake/man/dmake.tf continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 20; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test -f _shar_wnt_.tmp; then
- sed 's/^X//' << 'SHAR_EOF' >> 'dmake/man/dmake.tf' &&
- This macro gives the set of flags to pass to the shell when
- invoking it to execute a single line recipe. The value of the macro is the
- list of flags with a leading switch indicator. (ie. `-' under UNIX)
- .IP \fBSHELLMETAS\fP 1.6i
- Each time
- .B dmake
- executes a single recipe line (not a group recipe) the line is
- searched for any occurrence of a character defined in the value of SHELLMETAS.
- If such a character is found the recipe line is defined to require a shell
- to ensure its correct execution. In such instances
- a shell is used to invoke the recipe line.
- If no match is found the recipe line is executed without the use of a shell.
- .sp
- .PP
- There is only one character valued macro defined by \fBdmake\fP:
- \fBSWITCHAR\fP contains the switch character used
- to introduce options on command lines. For UNIX its value is '-', and for
- MSDOS its value may be '/' or '-'.
- The macro is internally defined and is not user setable.
- The MSDOS version of \fBdmake\fP attempts to first extract SWITCHAR from an
- environment variable of the same name. If that fails it then attempts to
- use the undocumented getswitchar system call, and returns the result of
- that. Under MSDOS version 4.0 you must set the value of the environment
- macro SWITCHAR to '/' to obtain predictable behavior.
- .PP
- All boolean macros currently understood by
- .B dmake
- correspond directly to the previously defined attributes.
- These macros provide
- a second way to apply global attributes, and represent the
- preferred method of doing so. They are used by assigning them a
- value. If the value is not a NULL string then the boolean condition
- is set to on.
- If the value is a NULL string then the condition is set to off.
- There are five conditions defined and they correspond directly to the
- attributes of the same name. Their meanings are defined in the ATTRIBUTES
- section above.
- The macros are:
- \&\fB.EPILOG\fP,
- \&\fB.IGNORE\fP,
- \&\fB.MKSARGS\fP,
- \&\fB.NOINFER\fP,
- \&\fB.PRECIOUS\fP,
- \&\fB.PROLOG\fP,
- \&\fB.SEQUENTIAL\fP,
- \&\fB.SILENT\fP,
- \&\fB.SWAP\fP, and
- \&\fB.USESHELL\fP.
- Assigning any of these a non NULL value will globally set
- the corresponding attribute to on.
- .SH "RUN_TIME MACROS"
- These macros are defined
- when \fBdmake\fP is making targets, and may take on different values for each
- target. \fB$@\fP is defined to be the full target name, \fB$?\fP is the
- list of all out of date prerequisites, \fB$&\fP is the list of all
- prerequisites, \fB$>\fP is the name of the library if the current target is a
- library member, and
- \fB$<\fP is the list of prerequisites specified in the current rule.
- If the current target had a recipe inferred then \fB$<\fP is the name of the
- inferred prerequisite even if the target had a list of prerequisites supplied
- using an explicit rule that did not provide a recipe. In such situations
- \fB$&\fP gives the full list of prerequisites.
- .PP
- \fB$*\fP is defined as
- \fB$(@:db)\fP when making targets with explicit recipes and is defined as the
- value of % when making targets whose recipe is the result of an inference.
- In the first case \fB$*\fP is the target name with no suffix,
- and in the second case, is the value of the matched % pattern from
- the associated %-rule.
- \fB$^\fP expands to the set of out of date prerequisites taken from the
- current value of \fB$<\fP.
- In addition to these,
- \fB$$\fP expands to $, \fB{{\fP expands to {, \fB}}\fP expands to }, and the
- strings \fB<+\fP and \fB+>\fP are recognized
- as respectively starting and terminating a text diversion when they appear
- literally together in the same input line.
- .PP
- The difference between $? and $^ can best be illustrated by an example,
- consider:
- .RS
- .sp
- .nf
- fred.out : joe amy hello
- \trules for making fred
- X
- fred.out : my.c your.h his.h her.h # more prerequisites
- .fi
- .sp
- .RE
- Assume joe, amy, and my.c are newer then fred.out. When
- .B dmake
- executes the recipe for making fred.out the values of the following macros
- will be:
- .RS
- .sp
- .nf
- .Is "$@ "
- .Ii "$@"
- --> fred.out
- .Ii "$*"
- --> fred
- .Ii "$?"
- --> joe amy my.c # note the difference between $? and $^
- .Ii "$^"
- --> joe amy
- .Ii "$<"
- --> joe amy hello
- .Ii "$&"
- --> joe amy hello my.c your.h his.h her.h
- .fi
- .sp
- .RE
- .SH "FUNCTION MACROS"
- .B dmake
- supports a full set of functional macros. One of these, the $(mktmp ...)
- macro, is discussed in detail in the TEXT DIVERSION section and is not
- covered here.
- .RS
- .sp
- .IP "$(\fBnull\fP,\fItext\fP \fBtrue\fP \fBfalse\fP)"
- expands the value of
- .I text.
- If it is NULL then the macro returns the value of the expansion of \fBtrue\fP
- and the expansion of \fBfalse\fP otherwise. The terms \fBtrue\fP, and
- \fBfalse\fP must be strings containing no white\-space.
- .IP "$(\fB!null\fP,\fItext\fP \fBtrue\fP \fBfalse\fP)"
- Behaves identically to the previous macro except that the
- .B true
- string is chosen if the expansion of
- .I text
- is not NULL.
- .IP "$(\fBeq\fP,\fItext_a\fP,\fItext_b\fP \fBtrue\fP \fBfalse\fP)"
- expands
- .I text_a
- and
- .I text_b
- and compares their results. If equal it returns the result of the expansion
- of the
- .B true
- term, otherwise it returns the expansion of the
- .B false
- term.
- .IP "$(\fB!eq\fP,\fItext_a\fP,\fItext_b\fP \fBtrue\fP \fBfalse\fP)"
- Behaves identically to the previous macro except that the
- .B true
- string is chosen if the expansions of the two strings are not equal
- .IP "$(\fBshell\fP \fBcommand\fP)"
- Runs \fIcommand\fP as if it were part of a recipe and returns,
- separated by a single space, all the non-white
- space terms written to stdout by the command.
- For example:
- .RS
- .RS
- .sp
- $(shell ls *.c)
- .sp
- .RE
- will return \fI"a.c b.c c.c d.c"\fP if the files exist in the current
- directory. The recipe modification flags \fB[+@%-]\fP are honored if they
- appear as the first characters in the command. For example:
- .RS
- .sp
- $(shell +ls *.c)
- .sp
- .RE
- will run the command using the current shell.
- .RE
- .IP "$(\fBsort\fP \fBlist\fP)"
- Will take all white\-space separated tokens in \fIlist\fP and will
- return their sorted equivalent list.
- .IP "$(\fBstrip\fP \fBdata\fP)"
- Will replace all strings of white\-space in data by a single space.
- .IP "$(\fBsubst\fP,\fIpat\fP,\fIreplacement\fP \fBdata\fP)"
- Will search for \fIpat\fP in
- .B data
- and will replace any occurrence of
- .I pat
- with the
- .I replacement
- string.
- .RS
- The expansion
- .RS
- .sp
- $(subst,.o,.c $(OBJECTS))
- .sp
- .RE
- is equivalent to:
- .RS
- .sp
- $(OBJECTS:s/.o/.c/)
- .sp
- .RE
- .RE
- .SH "DYNAMIC PREREQUISITES"
- .B dmake
- looks for prerequisites whose names contain macro expansions during target
- processing. Any such prerequisites are expanded and the result of the
- expansion is used as the prerequisite name. As an example the line:
- .sp
- \tfred : $$@.c
- .sp
- causes the $$@ to be expanded when \fBdmake\fP is making fred, and it resolves
- to the target \fIfred\fP.
- This enables dynamic prerequisites to be generated. The value
- of @ may be modified by any of the valid macro modifiers. So you can say for
- example:
- .sp
- \tfred.out : $$(@:b).c
- .sp
- where the $$(@:b) expands to \fIfred\fP.
- Note the use of $$ instead of $ to indicate the dynamic expansion, this
- is due to the fact that the rule line is expanded when it is initially parsed,
- and $$ then returns $ which later triggers the dynamic prerequisite expansion.
- If you really want a $ to be part of a prerequisite name you must use $$$$.
- Dynamic macro expansion is performed in all user defined rules,
- and the special targets .SOURCE*, and .INCLUDEDIRS.
- .SH "BINDING TARGETS"
- This operation takes a target name and binds it to an existing file, if
- possible.
- .B dmake
- makes a distinction between the internal target name of a target and its
- associated external file name.
- Thus it is possible for a target's internal name and its external
- file name to differ.
- To perform the binding, the following set of rules is used.
- Assume that we are
- trying to bind a target whose name is of the form \fIX.suff\fP,
- where \fI.suff\fP is the suffix and \fIX\fP is the stem portion
- (ie. that part which contains the directory and the basename).
- .B dmake
- takes this target name and performs a series of search operations that try to
- find a suitably named file in the external file system.
- The search operation is user controlled
- via the settings of the various .SOURCE targets.
- .RS
- .IP 1.
- If target has the .SYMBOL attribute set then look for it in the library.
- If found, replace the target name with the library member name and continue
- with step 2. If the name is not found then return.
- .IP 2.
- Extract the suffix portion (that following the `.') of the target name.
- If the suffix is not null, look up the special target .SOURCE.<suff>
- (<suff> is the suffix).
- If the special target exists then search each directory given in
- the .SOURCE.<suff> prerequisite list for the target.
- If the target's suffix was null (ie. \fI.suff\fP was empty) then
- perform the above search but use the special target .SOURCE.NULL instead.
- If at any point a match is found then terminate the search.
- If a directory in the prerequisite list is the special name `.NULL ' perform
- a search for the full target name without prepending any directory portion
- (ie. prepend the NULL directory).
- (a default target of '.SOURCE : .NULL' is defined by \fBdmake\fP at startup,
- and is user redefinable)
- .IP 3.
- The search in step 2. failed. Repeat the same search but this time
- use the special target .SOURCE.
- .IP 4.
- The search in step 3. failed.
- If the target has the library member attribute (.LIBMEMBER)
- set then try to find the target in the library which was passed along
- with the .LIBMEMBER attribute (see the MAKING LIBRARIES section).
- The bound file name assigned to a target which is successfully
- located in a library is the same name that would be assigned had the search
- failed (see 5.).
- .IP 5.
- The search failed. Either the target was not found in any of the search
- directories or no applicable .SOURCE special targets exist.
- If applicable .SOURCE special targets exist, but the target was not found,
- then \fBdmake\fP assigns the first name searched as the bound file name.
- If no applicable .SOURCE special targets exist,
- then the full original target name becomes the bound file name.
- .RE
- .PP
- There is potential here for a lot of search operations. The trick is to
- define .SOURCE.x special targets with short search lists and leave .SOURCE
- as short as possible.
- The search algorithm has the following useful side effect.
- When a target having the .LIBMEMBER (library member) attribute is searched for,
- it is first searched for as an ordinary file.
- When a number of library members require updating it is desirable to compile
- all of them first and to update the library at the end in a single operation.
- If one of the members does not compile and \fBdmake\fP stops, then
- the user may fix the error and make again. \fBdmake\fP will not remake any
- of the targets whose object files have already been generated as long as
- none of their prerequisite files have been modified as a result of the fix.
- .PP
- When defining .SOURCE and .SOURCE.x targets the construct
- .sp
- \t.SOURCE :
- .br
- \t.SOURCE : fred gery
- .sp
- is equivalent to
- .sp
- \t.SOURCE :- fred gery
- .PP
- \fBdmake\fP correctly handles the UNIX Make variable VPATH. By definition VPATH
- contains a list of ':' separated directories to search when looking for a
- target. \fBdmake\fP maps VPATH to the following special rule:
- .sp
- \t.SOURCE :^ $(VPATH:s/:/ /)
- .sp
- Which takes the value of VPATH and sets .SOURCE to the same set of directories
- as specified in VPATH.
- .SH "PERCENT(%) RULES AND MAKING INFERENCES"
- When \fBdmake\fP makes a target, the target's set of prerequisites (if any)
- must exist and the target must have a recipe which \fBdmake\fP
- can use to make it.
- If the makefile does not specify an explicit recipe for the target then
- .B dmake
- uses special rules to try to infer a recipe which it can use
- to make the target. Previous versions of Make perform this task by using
- rules that are defined by targets of the form .<suffix>.<suffix> and by
- using the .SUFFIXES list of suffixes. The exact workings of this mechanism
- were sometimes difficult to understand and often limiting in their usefulness.
- Instead, \fBdmake\fP supports the concept of \fI%-meta\fP rules.
- The syntax and semantics of these rules differ from standard rule lines as
- follows:
- .sp
- .nf
- .RS
- \fI<%-target>\fP [\fI<attributes>\fP] \fI<ruleop>\fP [\fI<%-prerequisites>\fP] [;\fI<recipe>\fP]
- .RE
- .fi
- .sp
- where \fI%-target\fP is a target containing exactly a single `%' sign,
- .I attributes
- is a list (possibly empty) of attributes,
- .I ruleop
- is the standard set of rule operators,
- .I "%-prerequisites"
- \&, if present, is a list of prerequisites containing zero or more `%' signs,
- and
- .I recipe,
- if present, is the first line of the recipe.
- .PP
- The
- .I %-target
- defines a pattern against which a target whose recipe is
- being inferred gets matched. The pattern match goes as follows: all chars are
- matched exactly from left to right up to but not including the % sign in the
- pattern, % then matches the longest string from the actual target name
- not ending in
- the suffix given after the % sign in the pattern.
- Consider the following examples:
- .RS
- .sp
- .nf
- .Is "dir/%.c "
- .Ii "%.c"
- matches fred.c but not joe.c.Z
- .Ii "dir/%.c"
- matches dir/fred.c but not dd/fred.c
- .Ii "fred/%"
- matches fred/joe.c but not f/joe.c
- .Ii "%"
- matches anything
- .fi
- .sp
- .RE
- In each case the part of the target name that matched the % sign is retained
- and is substituted for any % signs in the prerequisite list of the %-meta rule
- when the rule is selected during inference and
- .B dmake
- constructs the new dependency.
- As an example the following %-meta rules describe the following:
- .RS
- .sp
- %.c : %.y ; recipe...
- .sp
- .RE
- describes how to make any file ending in .c if a corresponding file ending
- in .y can be found.
- .RS
- .sp
- foo%.o : fee%.k ; recipe...
- .sp
- .RE
- is used to describe how to make fooxxxx.o from feexxxx.k.
- .RS
- .sp
- %.a :; recipe...
- .sp
- .RE
- describes how to make a file whose suffix is .a without inferring any
- prerequisites.
- .RS
- .sp
- %.c : %.y yaccsrc/%.y ; recipe...
- .sp
- .RE
- is a short form for the construct:
- .RS
- .sp
- %.c : %.y ; recipe...
- .br
- %.c : yaccsrc/%.y ; recipe...
- .sp
- .RE
- ie. It is possible to specify the same recipe for two %-rules by giving
- more than one prerequisite in the prerequisite list.
- A more interesting example is:
- .RS
- .sp
- % : RCS/%,v ; co $@
- .sp
- .RE
- which describes how to take any target and check it out of
- the RCS directory if the corresponding file exists in the RCS directory.
- The equivalent SCCS rule would be:
- .RS
- .sp
- % : s.% ; get $@
- .sp
- .RE
- .PP
- The previous RCS example defines an infinite rule, because it says how to make
- .I anything
- from RCS/%,v, and
- .I anything
- also includes RCS/fred.c,v.
- To limit the size of the graph that results from such rules
- .B dmake
- uses the macro variable PREP (stands for % repetition). By default the value
- of this variable is 0, which says that no repetitions of a %-rule are to be
- generated. If it is set to something greater than 0, then that many
- repetitions of any infinite %-rule are allowed. If in the above
- example PREP was set to 1, then \fBdmake\fP would generate the dependency
- graph:
- .RS
- .sp
- % --> RCS/%,v --> RCS/RCS/%,v,v
- .sp
- .RE
- Where each link is assigned the same recipe as the first link.
- PREP should be used only in special cases, since it may result in
- a large increase in the number of possible prerequisites tested.
- .B dmake
- further assumes that any target that has no suffix can be made from
- a prerequisite that has at least one suffix.
- .PP
- .B dmake
- supports dynamic prerequisite generation for prerequisites of %-meta rules.
- This is best illustrated by an example. The RCS rule shown above can infer
- how to check out a file from a corresponding RCS file only if the target
- is a simple file name with no directory information. That is, the above rule
- can infer how to find \fIRCS/fred.c,v\fP from the target \fIfred.c\fP,
- but cannot infer how to find \fIsrcdir/RCS/fred.c,v\fP from \fIsrcdir/fred.c\fP
- because the above rule will cause \fBdmake\fP to look for RCS/srcdir/fred.c,v;
- which does not exist (assume that srcdir has its own RCS directory as is the
- common case).
- .PP
- A more versatile formulation of the above RCS check out rule is the following:
- .RS
- .sp
- % : $$(@:d)RCS/$$(@:f),v : co $@
- .sp
- .RE
- This rule uses the dynamic macro $@ to specify the prerequisite to try to
- infer. During inference of this rule the macro $@ is set to the value of
- the target of the %-meta rule and the appropriate prerequisite is generated by
- extracting the directory portion of the target name (if any), appending the
- string \fIRCS/\fP to it, and appending the target file name with a trailing
- \fI,v\fP attached to the previous result.
- .PP
- .B dmake
- can also infer indirect prerequisites.
- An inferred target can have a list of prerequisites added that will not
- show up in the value of $< but will show up in the value of $? and $&.
- Indirect prerequisites are specified in an inference rule by quoting the
- prerequisite with single quotes. For example, if you had the explicit
- dependency:
- .RS
- .sp
- .nf
- fred.o : fred.c ; rule to make fred.o
- fred.o : local.h
- .fi
- .sp
- .RE
- then this can be inferred for fred.o from the following inference rule:
- .RS
- .sp
- %.o : %.c 'local.h' ; rule to make a .o from a .c
- .sp
- .RE
- You may infer indirect prerequisites that are a function of the value of '%'
- in the current rule. The meta-rule:
- .RS
- .sp
- %.o : %.c '$(INC)/%.h' ; rule to make a .o from a .c
- .sp
- .RE
- infers an indirect prerequisite found in the INC directory whose name is the
- same as the expansion of $(INC), and the prerequisite name depends on the
- base name of the current target.
- The set of indirect prerequisites is attached to the meta rule in which they
- are specified and are inferred only if the rule is used to infer a recipe
- for a target. They do not play an active role in driving the inference
- algorithm.
- The construct:
- .RS
- .sp
- %.o : %.c %.f 'local.h'; recipe
- .sp
- .RE
- is equivalent to:
- .RS
- .sp
- .nf
- %.o : %.c 'local.h' : recipe
- %.o : %.f 'local.h' : recipe
- .fi
- .sp
- .RE
- .PP
- If any of the attributes .SETDIR, .EPILOG, .PROLOG, .SILENT,
- \&.USESHELL, .SWAP, .PRECIOUS, .LIBRARY, .NOSTATE and .IGNORE
- are given for a %-rule then when that rule is bound to a target
- as the result of an inference, the target's set of attributes is augmented by
- the attributes from the above set that are specified in the bound %-rule.
- Other attributes specified for %-meta rules are not inherited by the target.
- The .SETDIR attribute is treated in a special way.
- If the target already had a .SETDIR attribute set then
- .B dmake
- changes to that directory prior to performing the inference.
- During inference any .SETDIR attributes for the inferred prerequisite
- are honored.
- The directories must exist for a %-meta rule to be selected as a possible
- inference path. If the directories do not exist no error message is issued,
- instead the corresponding path in the inference graph is rejected.
- .PP
- .B dmake
- also supports the old format special target .<suffix>.<suffix>
- by identifying any rules
- of this form and mapping them to the appropriate %-rule. So for example if
- an old makefile contains the construct:
- .RS
- .sp
- \&.c.o :; cc -c $< -o $@
- .sp
- .RE
- .B dmake
- maps this into the following %-rule:
- .RS
- .sp
- %.o : %.c; cc -c $< -o $@
- .sp
- .RE
- Furthermore,
- .B dmake
- understands several SYSV AUGMAKE special targets and maps them into
- corresponding %-meta rules. These transformation must be enabled by providing
- the -A flag on the command line or by setting the value of AUGMAKE to
- non\-NULL.
- The construct
- .RS
- .sp
- \&.suff :; recipe
- .sp
- .RE
- gets mapped into:
- .RS
- .sp
- % : %.suff; recipe
- .sp
- .RE
- and the construct
- .RS
- .sp
- \&.c~.o :; recipe
- .sp
- .RE
- gets mapped into:
- .RS
- .sp
- %.o : s.%.c ; recipe
- .sp
- .RE
- In general, a special target of the form .<str>~ is replaced by the %-rule
- construct s.%.<str>, thereby providing support for the syntax used by SYSV
- AUGMAKE for providing SCCS support.
- When enabled, these mappings allow processing of existing SYSV
- makefiles without modifications.
- .PP
- .B dmake
- bases all of its inferences on the inference graph constructed from the
- %-rules defined in the makefile.
- It knows exactly which targets can be made from which prerequisites by
- making queries on the inference graph. For this reason .SUFFIXES is not
- needed and is completely ignored.
- .PP
- For a %-meta rule to be inferred as the
- rule whose recipe will be used to make a target, the target's name must match
- the %-target pattern, and any inferred %-prerequisite must already exist or
- have an explicit recipe so that the prerequisite can be made.
- Without \fItransitive closure\fP on the inference graph the above rule
- describes precisely when an inference match terminates the search.
- If transitive closure is enabled (the usual case), and a prerequisite does
- not exist or cannot be made, then
- .B dmake
- invokes the inference algorithm recursively on the prerequisite to see if
- there is some way the prerequisite can be manufactured. For, if the
- prerequisite can be made then the current target can also be made using the
- current %-meta rule.
- This means that there is no longer a need to give a rule
- for making a .o from a .y if you have already given a rule for making a .o
- from a .c and a .c from a .y. In such cases
- .B dmake
- can infer how to make the
- \&.o from the .y via the intermediary .c and will remove the .c when the .o is
- made. Transitive closure can be disabled by giving the -T switch on the
- command line.
- .PP
- A word of caution.
- .B dmake
- bases its transitive closure on the %-meta rule targets.
- When it performs transitive closure it infers how to make a target from a
- prerequisite by performing a pattern match as if the potential prerequisite
- were a new target.
- The set of rules:
- .RS
- .nf
- .sp
- %.o : %.c :; rule for making .o from .c
- %.c : %.y :; rule for making .c from .y
- % : RCS/%,v :; check out of RCS file
- .fi
- .sp
- .RE
- will, by performing transitive closure, allow \fBdmake\fP to infer how to make
- a .o from a .y using a .c as an intermediate temporary file. Additionally
- it will be able to infer how to make a .y from an RCS file, as long as that
- RCS file is in the RCS directory and has a name which ends in .y,v.
- The transitivity computation is performed dynamically for each target that
- does not have a recipe. This has potential to be costly if the %-meta
- rules are not carefully specified. The .NOINFER attribute is used to mark
- a %-meta node as being a final target during inference. Any node with this
- attribute set will not be used for subsequent inferences. As an example
- the node RCS/%,v is marked as a final node since we know that if the RCS file
- does not exist there likely is no other way to make it. Thus the standard
- startup makefile contains an entry similar to:
- .RS
- .nf
- \&.NOINFER : RCS/%,v
- .fi
- .RE
- Thereby indicating that the RCS file is the end of the inference chain.
- X
- Whenever the inference algorithm determines that a target can be made from
- more than one prerequisite and the inference chains for the two methods
- are the same length the algorithm reports an ambiguity and prints the
- ambiguous inference chains.
- .PP
- .B dmake
- tries to
- remove intermediate files resulting from transitive closure if the file
- is not marked as being PRECIOUS, or the \fB-u\fP flag was not given on the
- command line, and if the inferred intermediate did not previously exist.
- Intermediate targets that existed prior to being made are never removed.
- This is in keeping with the philosophy that
- .B dmake
- should never remove things from the file system that it did not add.
- If the special target .REMOVE is defined and has a recipe then
- .B dmake
- constructs a list of the intermediate files to be removed and makes them
- prerequisites of .REMOVE. It then makes .REMOVE thereby removing the
- prerequisites if the recipe of .REMOVE says to. Typically .REMOVE is defined
- in the startup file as:
- .sp
- \t.REMOVE :; $(RM) $<
- .SH "MAKING TARGETS"
- In order to update a target \fBdmake\fP must execute a recipe.
- When a recipe needs to be executed it is first expanded so that any macros
- in the recipe text are expanded, and it is then either executed directly or
- passed to a shell.
- .B dmake
- supports two types of recipes. The regular recipes and group recipes.
- .PP
- When a regular recipe is invoked \fBdmake\fP executes each line of the recipe
- separately using a new copy of a shell if a shell is required.
- Thus effects of commands do not generally persist across recipe lines.
- (e.g. cd requests in a recipe line do not carry over to the next recipe line)
- The decision on whether a shell is required to execute a command is based on
- the value of the macro SHELLMETAS or on the specification of '+' or .USESHELL
- for the current recipe or target respectively.
- If any character in the value of
- SHELLMETAS is found in the expanded recipe text-line or the use of a shell
- is requested explicitly via '+' or .USESHELL then the command is
- executed using a shell, otherwise the command is executed directly.
- The shell that is used for execution is given by the value of the macro SHELL.
- The flags that are passed to the shell are given by the value of SHELLFLAGS.
- Thus \fBdmake\fP constructs the command line:
- .sp
- \t$(SHELL) $(SHELLFLAGS) $(expanded_recipe_command)
- .sp
- Normally
- .B dmake
- writes the command line that it is about to invoke to standard output.
- If the .SILENT attribute is set for the target or for
- the recipe line (via @), then the recipe line is not echoed.
- .PP
- Group recipe processing is similar to that of regular recipes, except that
- a shell is always invoked. The shell that is invoked is given by the value of
- the macro GROUPSHELL, and its flags are taken from the value of the macro
- GROUPFLAGS. If a target has the .PROLOG attribute set then
- .B dmake
- prepends to the shell script the recipe associated with the special target
- \&.GROUPPROLOG, and if the attribute .EPILOG is set as well, then the recipe
- associated with the special target .GROUPEPILOG is appended to the script
- file.
- This facility can be used to always prepend a common header and common trailer
- to group recipes.
- Group recipes are echoed to standard output just like standard recipes, but
- are enclosed by lines beginning with [ and ].
- .PP
- The recipe flags [+,-,%,@] are recognized at the start of a recipe line
- even if they appear in a macro. For example:
- .RS
- .sp
- .nf
- SH = +
- all:
- \t$(SH)echo hi
- .fi
- .sp
- .RE
- is completely equivalent to writing
- .RS
- .sp
- .nf
- SH = +
- all:
- \t+echo hi
- .fi
- .sp
- .RE
- .PP
- The last step performed by
- .B dmake
- prior to running a recipe is to set the macro CMNDNAME to the name of the
- command to execute (determined by finding the first white\-space ending token
- in the command line). It then sets the macro CMNDARGS to be the remainder
- of the line.
- .B dmake
- then expands the macro COMMAND which by default is set to
- .RS
- .sp
- COMMAND = $(CMNDNAME) $(CMNDARGS)
- .sp
- .RE
- The result of this final expansion is the command that will be executed.
- The reason for this expansion is to allow for a different interface to
- the argument passing facilities (esp. under DOS) than that provided by
- .B dmake\fR.\fP
- You can for example define COMMAND to be
- .RS
- .sp
- COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS))
- .sp
- .RE
- which dumps the arguments into a temporary file and runs the command
- .RS
- .sp
- $(CMNDNAME) @/tmp/ASAD23043
- .sp
- .RE
- which has a much shorter argument list. It is now up to the command to
- use the supplied argument as the source for all other arguments.
- As an optimization, if COMMAND is not defined
- .B dmake
- does not perform the above expansion. On systems, such as UNIX, that
- handle long command lines this provides a slight saving in processing the
- makefiles.
- .SH "MAKING LIBRARIES"
- Libraries are easy to maintain using \fBdmake\fP. A library is a file
- containing a collection of object files.
- Thus to make a library you simply specify it as a target with the .LIBRARY
- attribute set and specify its list of prerequisites. The prerequisites should
- be the object members that are to go into the library. When
- .B dmake
- makes the library target it uses the .LIBRARY attribute to pass to the
- prerequisites the .LIBMEMBER attribute and the name of the library. This
- enables the file binding mechanism to look for the member in the library if an
- appropriate object file cannot be found. A small example best illustrates
- this.
- .RS
- .nf
- .sp
- mylib.a .LIBRARY : mem1.o mem2.o mem3.o
- \trules for making library...
- \t# remember to remove .o's when lib is made
- .sp
- # equivalent to: '%.o : %.c ; ...'
- \&.c.o :; rules for making .o from .c say
- .sp
- .fi
- .RE
- .B dmake
- will use the .c.o rule for making the library members if appropriate .c files
- can be found using the search rules. NOTE: this is not specific in any way
- to C programs, they are simply used as an example.
- .PP
- .B dmake
- tries to handle the old library construct format in a sensible way.
- The construct
- .I lib(member.o)
- is separated and the \fIlib\fP portion is declared
- as a library target.
- The new target is defined
- with the .LIBRARY attribute set and the \fImember.o\fP portion of the
- construct is
- declared as a prerequisite of the lib target.
- If the construct \fIlib(member.o)\fP
- appears as a prerequisite of a target in the
- makefile, that target has the new name of the lib assigned as its
- prerequisite. Thus the following example:
- .RS
- .sp
- .nf
- a.out : ml.a(a.o) ml.a(b.o); $(CC) -o $@ $<
- X
- \&.c.o :; $(CC) -c $(CFLAGS) -o $@ $<
- %.a:
- \tar rv $@ $<
- \tranlib $@
- \trm -rf $<
- .sp
- .fi
- .RE
- constructs the following dependency
- graph.
- .RS
- .sp
- .nf
- a.out : ml.a; $(CC) -o $@ $<
- ml.a .LIBRARY : a.o b.o
- X
- %.o : %.c ; $(CC) -c $(CFLAGS) -o $@ $<
- %.a :
- \tar rv $@ $<
- \tranlib $@
- \trm -rf $<
- .sp
- .fi
- .RE
- and making a.out then works as expected.
- .PP
- The same thing happens for any target of the form \fIlib((entry))\fP.
- These targets have an
- additional feature in that the \fIentry\fP target has the .SYMBOL attribute
- set automatically.
- .PP
- NOTE: If the notion of entry points is supported by the archive and by
- \fBdmake\fP (currently not the case) then
- .B dmake
- will search the archive for the entry point and return not only the
- modification time of the member which defines the entry but also the name of
- the member file. This name will then replace \fIentry\fP and will be used for
- making the member file. Once bound to an archive member the .SYMBOL
- attribute is removed from the target.
- This feature is presently disabled as there is little standardization
- among archive formats, and we have yet to find a makefile utilizing this
- feature (possibly due to the fact that it is unimplemented in most versions
- of UNIX Make).
- .PP
- Finally, when
- .B dmake
- looks for a library member it must first locate the library file.
- It does so by first looking for the library relative to the current directory
- and if it is not found it then looks relative to the current value of
- $(TMD). This allows commonly used libraries to be kept near the root of
- a source tree and to be easily found by
- .B dmake\fR.\fP
- .SH "KEEP STATE"
- .B dmake
- supports the keeping of state information for targets that it makes whenever
- the macro .KEEP_STATE is assigned a value. The value of the macro should be
- the name of a state file that will contain the state information. If state
- keeping is enabled then each target that does not poses the .NOSTATE
- attribute will have a record written into the state file indicating the
- target's name, the current directory, the command used to update the target,
- and which, if any, :: rule is being used. When you make this target again
- if any of this information does not match the previous settings and the
- target is not out dated it will still be re\-made. The assumption is that one
- of the conditions above has changed and that we wish to remake the target.
- For example,
- state keeping is used in the maintenance of
- .B dmake
- to test compile different versions of the source using different compilers.
- Changing the compiler causes the compilation flags to be modified and hence
- all sources to be recompiled.
- .PP
- The state file is an ascii file and is portable, however it is
- not in human readable form as the entries represent hash keys of the above
- information.
- .PP
- The Sun Microsystem's Make construct
- .RS
- .sp
- \&.KEEP_STATE :
- .sp
- .RE
- is recognized and is mapped to \fB.KEEP_STATE:=_state.mk\fP.
- The
- .B dmake
- version of state keeping does not include scanning C source files for
- dependencies like Sun Make. This is specific to C programs and it was
- felt that it does not belong in make.
- .B dmake
- instead provides the tool, \fBcdepend\fP, to scan C source files and to produce
- depedency information. Users are free to modify cdepend to produce other
- dependency files. (NOTE:
- .B cdepend
- does not come with the distribution at this time, but will be available in
- a patch in the near future)
- .SH "MULTI PROCESSING"
- If the architecture supports it then \fBdmake\fP is capable of making a target's
- prerequisites in parallel. \fBdmake\fP will make as much in parallel as it
- can and use a number of child processes up to the maximum specified by
- MAXPROCESS or by the value supplied to the -P command line flag.
- A parallel make is enabled by setting the value of MAXPROCESS (either directly
- or via -P option) to a value which is > 1.
- \fBdmake\fP guarantees that all dependencies as specified in the makefile are
- honored. A target will not be made until all of its prerequisites have been
- made.
- If a parallel make is being performed then the following restrictions on
- parallelism are enforced.
- .RS
- .IP 1.
- Individual recipe lines in a non-group recipe are performed sequentially in
- the order in which they are specified within the makefile and in parallel with
- the recipes of other targets.
- .IP 2.
- If a target contains multiple recipe definitions (cf. :: rules) then these are
- performed sequentially in the order in which the :: rules are specified within
- the makefile and in parallel with the recipes of other targets.
- .IP 3.
- If a target rule contains the `!' modifier, then the recipe is performed
- sequentially for the list of outdated prerequisites and in parallel with the recipes of other targets.
- .IP 4.
- If a target has the .SEQUENTIAL attribute set then all of its prerequisites
- are made sequentially relative to one another (as if MAXPROCESS=1), but in
- parallel with other targets in the makefile.
- .RE
- .PP
- Note: If you specify a parallel make then
- the order of target update and the order in which the associated recipes are
- invoked will not correspond to that displayed by the -n flag.
- .SH "CONDITIONALS"
- .B dmake
- supports a makefile construct called a \fIconditional\fR. It allows
- the user
- to conditionally select portions of makefile text for input processing
- and to discard other portions. This becomes useful for
- writing makefiles that are intended to function for more than one target
- host and environment. The conditional expression is specified as follows:
- .sp
- .RS
- .nf
- \&.IF \fIexpression\fR
- X ... if text ...
- \&.ELIF \fIexpression\fR
- X ... if text ...
- \&.ELSE
- X ... else text ...
- \&.END
- .RE
- .fi
- .sp
- The .ELSE and .ELIF portions are optional, and the conditionals may be
- nested (ie. the text may contain another conditional).
- \&.IF, .ELSE, and .END
- may appear anywhere in the makefile, but a single conditional expression
- may not span multiple makefiles.
- .PP
- \fIexpression\fR can be one of the following three forms:
- .sp
- \t<text> | <text> == <text> | <text> != <text>
- .sp
- where \fItext\fR is either text or a macro expression. In any case,
- before the comparison is made, the expression is expanded. The text
- portions are then selected and compared. White space at the start and
- end of the text portion is discarded before the comparison. This means
- that a macro that evaluates to nothing but white space is considered a
- NULL value for the purpose of the comparison.
- In the first case the expression evaluates TRUE if the text is not NULL
- otherwise it evaluates FALSE. The remaining two cases both evaluate the
- expression on the basis of a string comparison.
- If a macro expression needs to be equated to a NULL string then compare it to
- the value of the macro $(NULL).
- You can use the $(shell ...) macro to construct more complex test expressions.
- .SH "EXAMPLES"
- .RS
- .nf
- .sp
- # A simple example showing how to use make
- #
- prgm : a.o b.o
- X cc a.o b.o -o prgm
- a.o : a.c g.h
- X cc a.c -o $@
- b.o : b.c g.h
- X cc b.c -o $@
- .fi
- .RE
- .sp
- In the previous
- example prgm is remade only if a.o and/or b.o is out of date with
- respect to prgm.
- These dependencies can be stated more concisely
- by using the inference rules defined in the standard startup file.
- The default rule for making .o's from .c's looks something like this:
- .sp
- \&\t%.o : %.c; cc -c $(CFLAGS) -o $@ $<
- .sp
- Since there exists a rule (defined in the startup file)
- for making .o's from .c's
- \fBdmake\fR will use that rule
- for manufacturing a .o from a .c and we can specify our dependencies
- more concisely.
- .sp
- .RS
- .nf
- prgm : a.o b.o
- X cc -o prgm $<
- a.o b.o : g.h
- .fi
- .RE
- .sp
- A more general way to say the above using the new macro expansions
- would be:
- .sp
- .RS
- .nf
- SRC = a b
- OBJ = {$(SRC)}.o
- .sp
- prgm : $(OBJ)
- X cc -o $@ $<
- .sp
- $(OBJ) : g.h
- .fi
- .RE
- .sp
- If we want to keep the objects in a separate directory, called
- objdir, then we would write
- something like this.
- .sp
- .RS
- .nf
- SRC = a b
- OBJ = {$(SRC)}.o
- .sp
- prgm : $(OBJ)
- X cc $< -o $@
- .sp
- $(OBJ) : g.h
- \&%.o : %.c
- X $(CC) -c $(CFLAGS) -o $(@:f) $<
- X mv $(@:f) objdir
- X
- \&.SOURCE.o : objdir # tell make to look here for .o's
- .fi
- .RE
- .sp
- An example of building library members would go something like this:
- (NOTE: The same rules as above will be used to produce .o's from .c's)
- .sp
- .RS
- .nf
- SRC\t= a b
- LIB\t= lib
- LIBm\t= { $(SRC) }.o
- .sp
- prgm: $(LIB)
- X cc -o $@ $(LIB)
- .sp
- $(LIB) .LIBRARY : $(LIBm)
- X ar rv $@ $<
- X rm $<
- .fi
- .RE
- .sp
- Finally, suppose that each of the source files in the previous example had
- the `:' character in their target name. Then we would write the above example
- as:
- .sp
- .RS
- .nf
- SRC\t= f:a f:b
- LIB\t= lib
- LIBm\t= "{ $(SRC) }.o" # put quotes around each token
- .sp
- prgm: $(LIB)
- X cc -o $@ $(LIB)
- .sp
- $(LIB) .LIBRARY : $(LIBm)
- X ar rv $@ $<
- X rm $<
- .fi
- .RE
- .SH "COMPATIBILITY"
- There are two notable differences between
- .B \fBdmake\fR
- and the standard version of BSD UNIX 4.2/4.3 Make.
- .RS
- .IP 1. .3i
- BSD UNIX 4.2/4.3 Make supports wild card filename expansion for
- prerequisite names. Thus if a directory contains a.h, b.h and c.h, then a
- line like
- .sp
- \ttarget: *.h
- .sp
- will cause UNIX make to expand the *.h into "a.h b.h c.h". \fBdmake\fR
- does not support this type of filename expansion.
- .IP 2. .3i
- Unlike UNIX make, touching a library member causes \fBdmake\fR
- to search the library for the member name and to update the library time stamp.
- This is only implemented in the UNIX version.
- MSDOS and other versions may not have librarians that keep file time stamps,
- as a result \fBdmake\fR touches the library file itself, and prints a warning.
- .RE
- .PP
- \fBdmake\fP is not compatible with GNU Make. In particular it does not
- understand GNU Make's macro expansions that query the file system.
- .PP
- .B dmake
- is fully compatible with SYSV AUGMAKE, and supports the following AUGMAKE
- features:
- .RS
- .IP 1. .3i
- The word \fBinclude\fP appearing at the start of a line can be used instead of
- the ".INCLUDE :" construct understood by \fBdmake\fP.
- .IP 2. .3i
- The macro modifier expression $(macro:str=sub) is understood and is equivalent
- to the expression $(macro:s/str/sub), with the restriction that str must match
- the following regular expression:
- .sp
- \tstr[ |\\t][ |\\t]*
- .sp
- (ie. str only matches at the end of a token where str is a suffix and is
- terminated by a space, a tab, or end of line)
- .IP 3.
- The macro % is defined to be $@ (ie. $% expands to the same value as $@).
- .IP 4.
- The AUGMAKE notion of libraries is handled correctly.
- .IP 5.
- When defining special targets for the inference rules and the AUGMAKE special
- target handling is enabled then the special target
- \&.X is equivalent to the %-rule "% : %.X".
- .IP 6.
- Directories are always made if you specify \fB-A\fP. This is consistent
- with other UNIX versions of Make.
- .IP 7.
- Makefiles that utilize virtual targets to force making of other targets work
- SHAR_EOF
- true || echo 'restore of dmake/man/dmake.tf failed'
- fi
- echo 'End of part 20, continue with part 21'
- echo 21 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-